﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ProgNetComponentsDx.Enums;
using ProgNetComponentsDx.Options;
using Microsoft.Win32;
using DevExpress.XtraEditors;
using ProgNetComponentsDx.Browsers;
using DevExpress.XtraTab;
using ProgNetComponents.Classes;
using ProgNetComponents.Data.SqlCe;

namespace BuildHelper.Setup.Opcje
{
    public partial class FormOpcje : XtraForm, IDataForm
    {
        private static FormOpcje _instance;
        public static string GetOptionPath(object optionId)
        {
            if (_instance == null)
            {
                _instance = new FormOpcje();
            }
            return _instance.optionProvider1.GetOptionPath(optionId);
        }

        public FormOpcje()
        {
            InitializeComponent();
            if (Program.IsDebug)
            {
                if (!CheckDebug(this))
                {
                    this.ShowDxInfoDialog("Błąd w opcjach.");
                }
            }
            int minSize = 120;
            List<XtraTabControl> tabs = new List<XtraTabControl>()
            {
                tabControlMain,
                tabControlDefinicje,
                tabControlRozne,
                tabControlWork
            };
            foreach(XtraTabControl t in tabs)
                t.SetTabMinSize(minSize);

          
        }
        private Dictionary<object, Control> added = new Dictionary<object, Control>();

        private bool CheckDebug(Control control)
        {
            OptionSettings s =null;
            Exception ex = null;
            bool res = true;
            foreach (Control c in control.Controls)
            {
                if (c is BaseEdit)
                {
                    s = optionProvider1.GetSettings(c);
                    if (s == null || s.OptionId == null)
                    {
                        ex.LogInternal(" DEBUG OPCJE: Kontrolka bez opcji:" + c.Name + " [ "+c.GetLocation() + " ]");
                        res = false;
                    }
                    else
                    {
                        if (added.ContainsKey(s.OptionId))
                        {
                            ex.LogInternal(" DEBUG OPCJE: Podwojna Opcja: " + s.OptionId + " [" + c.Name  + " [ "+c.GetLocation() + " ], " + added[s.OptionId].Name+ " [ "+c.GetLocation() + " ] ]");
                            res = false;
                        }
                        else
                        {
                            added.Add(s.OptionId, c);
                        }
                    }
                }
                else
                {
                    if (!CheckDebug(c))
                        res = false;
                }
            }
            return res;
        }
        private string ValidationMessage;

        protected virtual bool Save()
        {
            optionProvider1.UnLockAllObjects();
            optionProvider1.CommitAllOptions();
            optionProvider1.LockAllObjects();

            (OptionCache.Grabber as SqlCeOptionGrabber).CustomSaveOperation = new Func<ProgNetComponents.Data.SqlCe.SqlCeDataManager, bool>((m) =>
            {
                m.AddTableDef(this.opcjeDataSet1.STP_EDYTORY, "SELECT * FROM STP_EDYTORY");

                bool result = m.UpdateDataSet(opcjeDataSet1);
                return result;
            });
            bool res = OptionCache.SaveOptions();
            (OptionCache.Grabber as SqlCeOptionGrabber).CustomSaveOperation = null;

            if (res)
            {
                BrowserCache.RefreshCache(opcjeDataSet1);
            }

            try
            {
                RegistryKey key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", RegistryKeyPermissionCheck.ReadWriteSubTree, System.Security.AccessControl.RegistryRights.FullControl);

                if (res && key != null)
                {
                    if (OptionCache.GetOptionBoolValue(Init.InitFormOptionNames.Rozne_Group.Uruchamianie.Autorun))
                    {
                        key.SetValue("BuildHelper4", Application.ExecutablePath.AddDoubleQuotes());
                    }
                    else
                    {
                        key.DeleteValue("BuildHelper4", false);
                    }
                }
            }
            catch
            {
                this.ShowDxInfoDialog("Problem z dodaniem wartości do rejestru. Sprawdź uprawnienia.");
            }
            return res;
        }
        protected virtual void FinishEdit()
        {
            //if (this.ActiveControl != null && this.ActiveControl is BaseEdit)
            //    (this.ActiveControl as BaseEdit).SendKey(new KeyEventArgs(Keys.Enter));
            this.SelectNextControl(this.ActiveControl, true, true, true, true);
        }
        protected virtual void SaveClick()
        {
            if (ValidateAll())
            {
                if (Save())
                {
                    modeProvider1.CurrentMode = FormMode.Read;
                    changeDetectorProvider1.ResetAll();
                }
                else
                {
                    this.ShowDxErrorDialog("Błąd zapisu!");
                }
            }
            else
            {
                if (ValidationMessage.IsNull())
                    ValidationMessage = "Błąd validacji.";

                this.ShowDxErrorDialog(ValidationMessage);
            }
        }

        protected virtual void EditClick()
        {

            if (modeProvider1.CurrentMode == FormMode.Read)
            {
                modeProvider1.CurrentMode = FormMode.Edit;
            }
            else
            {
                if (changeDetectorProvider1.HasChanges)
                {
                    DialogResult res = this.ShowDxYNCQuestionDialog("Zapisać zmiany?");
                    if (res == System.Windows.Forms.DialogResult.No)
                    {
                        optionProvider1.RefreshAllOptions();
                        changeDetectorProvider1.ResetAll();
                        modeProvider1.CurrentMode = FormMode.Read;
                    }
                    else if (res == System.Windows.Forms.DialogResult.Yes)
                    {
                        SaveClick();
                    }
                }
                else
                {
                    modeProvider1.CurrentMode = FormMode.Read;
                }
            }
        }

        protected virtual void RefreshClick()
        {
            optionProvider1.RefreshAllOptions();
            changeDetectorProvider1.ResetAll();
        }
        protected virtual bool ValidateAll()
        {
            bool result = false;
            ValidationMessage = "";
            dxErrorProvider1.ClearErrors();
            result = modeProvider1.ValidateRequiredEdits(ref ValidationMessage);
            if (!result)
            {
                IList<Control> controls = dxErrorProvider1.GetControlsWithError();
                if (controls.Count > 0)
                {
                    controls[0].Focus();
                    NavigateToControl(controls[0]);
                }
            }
            return result;
        }

        private void NavigateToControl(Control c)
        {
            if (c.Parent != null)
            {
                if (c.Parent is XtraTabPage)
                {
                    (c.Parent as XtraTabPage).TabControl.SelectedTabPage = (c.Parent as XtraTabPage);
                }
            }
            if (c.Parent == this || c.Parent == null)
                return;
            else NavigateToControl(c.Parent);
        }
        private bool ValidateBrowserData(BaseEdit sender, bool setDefError = true)
        {
            BrowserSettings s = browserProvider1.GetSettings(sender);
            if (s != null && s.Browser != null)
            {
                bool res =  s.Browser.IsValid(true, sender.EditValue);
                if (res)
                    dxErrorProvider1.SetError(sender, "");
                else if (setDefError)
                    dxErrorProvider1.SetError(sender, "Niepoprawna wartość");
                return res;
            }
            return true;
        }
        
        private void bbiZapisz_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            FinishEdit();
            SaveClick();
        }

        private void bbiEdytuj_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            FinishEdit();
            EditClick();
        }

        private void bbiRefresh_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            RefreshClick();
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            optionProvider1.LockAllObjects();
            using (SqlCeDataManager m = new SqlCeDataManager())
            {
                m.AddTableDef(this.opcjeDataSet1.STP_EDYTORY, "SELECT * FROM STP_EDYTORY");
                m.FillDataSet(opcjeDataSet1);
            }
            
            changeDetectorProvider1.ResetAll();
            modeProvider1.CurrentMode = FormMode.Edit;
            checkEdit5_CheckedChanged(null, null);
            rgTypNdrive_SelectedIndexChanged(null, null);
            radioGroup8_SelectedIndexChanged(null, null);
            radioGroup1_SelectedIndexChanged(null, null);
        }
        protected override void OnFormClosed(FormClosedEventArgs e)
        {
            base.OnFormClosed(e);
            optionProvider1.UnLockAllObjects();
        }
        private void radioGroup1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (opOtwieranieFormy.EditValue.AsString() == "W")
            {
                modeProvider1.GetSettings(opWybraneFormy).ReadOnlyModes = FormMode.Read | FormMode.View;
            }
            else
            {
                modeProvider1.GetSettings(opWybraneFormy).ReadOnlyModes = FormMode.All;
            }
        }

        private void changeDetectorProvider1_ContextChanged(object sender, EventArgs e)
        {
            if (changeDetectorProvider1.HasChanges)
            {
                if (!this.Text.EndsWith("*"))
                    this.Text += " *";
            }
            else
            {
                if (this.Text.EndsWith("*"))
                    this.Text = this.Text.Replace(" *", "");
            }
            modeProvider1.RefreshObject(bbiZapisz);
        }

        private void modeProvider1_CustomGetModes(object sender, ProgNetComponentsDx.Mode.CustomModeSettingsEventArgs e)
        {
            if (sender == bbiZapisz)
            {
                if (!changeDetectorProvider1.HasChanges)
                    e.IsReadOnly = true;
            }
        }
        protected override void OnClosing(CancelEventArgs e)
        {
            if (!Program.IsExit)
            {
                FinishEdit();
                if (changeDetectorProvider1.HasChanges)
                {
                    DialogResult dlg = this.ShowDxYNCQuestionDialog("Chcesz zapisać zmiany?");
                    switch (dlg)
                    {
                        case DialogResult.Cancel:
                            e.Cancel = true;
                            break;
                        case DialogResult.No:
                            break;
                        case DialogResult.Yes:
                            if (ValidateAll())
                            {
                                if (!Save())
                                {
                                    this.ShowDxErrorDialog("Błąd zapisu!");
                                    e.Cancel = true;
                                }
                            }
                            else
                            {
                                this.ShowDxWarningDialog("Błąd validacji.");
                                e.Cancel = true;
                            }
                            break;
                    }
                }
            }
            base.OnClosing(e);
        }
        #region IDataForm Members

        string IDataForm.Text
        {
            get { return Text; }
        }

        bool IDataForm.HasChanges
        {
            get { return changeDetectorProvider1.HasChanges; }
        }

        bool IDataForm.Save()
        {
            return Save();
        }

        bool IDataForm.ValidateAll()
        {
            return ValidateAll();
        }

        void IDataForm.FinishEdit()
        {
            FinishEdit();
        }

        #endregion

        private void simpleButton1_Click(object sender, EventArgs e)
        {
            BrowserCache.RefreshCacheForBrowser(Init.InitFormBrowserNames.Statyczne.FreeDrives);
            ObjectDialogResult res = BrowserCache.ShowBrowserDialog(Init.InitFormBrowserNames.Statyczne.FreeDrives);
            if (res.DialogResult == System.Windows.Forms.DialogResult.OK)
                teDyskBrancza.EditValue = res.Value;
        }

        private void simpleButton2_Click(object sender, EventArgs e)
        {
            teDyskBrancza.EditValue = null;
        }

        private void rgTypNdrive_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (rgTypNdrive.EditValue.AsString() == "G")
                modeProvider1.GetSettings(teDyskBrancza).RequiredModes = FormMode.All;
            else
                modeProvider1.GetSettings(teDyskBrancza).RequiredModes = FormMode.None;
        }

        private void gvONPExtEditors_InitNewRow(object sender, DevExpress.XtraGrid.Views.Grid.InitNewRowEventArgs e)
        {
            DataRow r = gvONPExtEditors.GetDataRow(e.RowHandle);
            if (r != null)
                r["STP_ED_TYP"] = "ONP";
        }

        private void repItemEdytorONP_ButtonClick(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)
        {
            if (modeProvider1.CurrentMode != FormMode.Read)
            {
                ButtonEdit edit = sender as ButtonEdit;
                if (edit != null)
                {
                    if (e.Button.Tag.AsString() == "DEL")
                        edit.EditValue = "";
                    else
                    {
                        if (edytorOpenFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                        {
                            edit.EditValue = edytorOpenFileDialog.FileName;
                        }
                    }
                }
            }
        }

        private void checkEdit5_CheckedChanged(object sender, EventArgs e)
        {
            if (checkEdit5.Checked)
            {
                modeProvider1.GetSettings(checkEditNieChowajErr).ReadOnlyModes = FormMode.Read | FormMode.View;
                modeProvider1.GetSettings(checkEditNieChowajWarn).ReadOnlyModes = FormMode.Read | FormMode.View;
            }
            else
            {
                modeProvider1.GetSettings(checkEditNieChowajErr).ReadOnlyModes = FormMode.All;
                checkEditNieChowajErr.Checked = true;
                modeProvider1.GetSettings(checkEditNieChowajWarn).ReadOnlyModes = FormMode.All;
                checkEditNieChowajWarn.Checked = true;
            }
        }

        private void gvONPExtEditors_CustomColumnDisplayText(object sender, DevExpress.XtraGrid.Views.Base.CustomColumnDisplayTextEventArgs e)
        {
            if (e.Column == colTyp)
            {
                DataRow r = gvONPExtEditors.GetDataRow(e.RowHandle);
                if (r != null)
                {
                    if (r["STP_ED_EXT"].IsNull() && r["STP_ED_EDYTOR"].IsNotNull())
                    {
                        e.DisplayText = "Globalny";
                    }
                    if (r["STP_ED_EXT"].IsNotNull() && r["STP_ED_EDYTOR"].IsNull())
                    {
                        e.DisplayText = "Domyślny";
                    }
                    if (r["STP_ED_EXT"].IsNotNull() && r["STP_ED_EDYTOR"].IsNotNull())
                    {
                        e.DisplayText = "Dla rozszeżenia";
                    }
                }
            }
        }

        private void radioGroup8_SelectedIndexChanged(object sender, EventArgs e)
        {
            string str = radioGroup8.EditValue.AsString();
            if (str == "N")
            {
                modeProvider1.GetSettings(teCommitMsgPrefix).ReadOnlyModes = FormMode.All;
                modeProvider1.GetSettings(ceCommitMsgLast).ReadOnlyModes = FormMode.All;
                modeProvider1.GetSettings(ceCommitMsgSummary).ReadOnlyModes = FormMode.All;
                modeProvider1.GetSettings(rgCommitMsgDS).ReadOnlyModes = FormMode.All;
            }
            else
            {
                modeProvider1.GetSettings(teCommitMsgPrefix).ReadOnlyModes = FormMode.Read | FormMode.View;
                if (str == "P")
                {
                    modeProvider1.GetSettings(ceCommitMsgLast).ReadOnlyModes = FormMode.All;
                    modeProvider1.GetSettings(ceCommitMsgSummary).ReadOnlyModes = FormMode.All;
                    modeProvider1.GetSettings(rgCommitMsgDS).ReadOnlyModes = FormMode.All;
                }
                else
                {
                    modeProvider1.GetSettings(ceCommitMsgLast).ReadOnlyModes = FormMode.Read | FormMode.View;
                    modeProvider1.GetSettings(ceCommitMsgSummary).ReadOnlyModes = FormMode.Read | FormMode.View;
                    modeProvider1.GetSettings(rgCommitMsgDS).ReadOnlyModes = FormMode.Read | FormMode.View;
                }
            }
        }
    }
}
